/*
 * MIT License
 *
 * Copyright (c) 2023-present, tangli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package tony.test.redis.aspect

import org.springframework.stereotype.Service
import tony.annotation.redis.RedisCacheEvict
import tony.annotation.redis.RedisCacheMapEvict
import tony.annotation.redis.RedisCacheable
import tony.annotation.redis.RedisCacheableMap
import tony.test.redis.util.SimpleObj
import tony.test.redis.util.TestIntEnum
import tony.test.redis.util.TestStringEnum
import java.math.BigDecimal
import java.util.Date

/**
 * JacksonRedisCacheAspect 切面测试用 Service
 *
 * 提供多类型方法用于 @RedisCacheable/@RedisCacheEvict 切面测试
 *
 * @author tony
 * @date 2025/07/01 17:00
 */
@Service
class JacksonRedisCacheAspectService {
    companion object {
        const val cacheKeyTemplate = "cacheKeyPrefix:#{key}:#{value}"
    }

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheBoolean(key: String, value: Boolean?): Boolean? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheInt(key: String, value: Int?): Int? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheLong(key: String, value: Long?): Long? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheBigDecimal(key: String, value: BigDecimal?): BigDecimal? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheString(key: String, value: String?): String? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheDate(key: String, value: Date?): Date? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheObj(key: String, value: SimpleObj?): SimpleObj? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheIntEnum(key: String, value: TestIntEnum?): TestIntEnum? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheStringEnum(key: String, value: TestStringEnum?): TestStringEnum? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheList(key: String, value: List<Any?>?): List<Any?>? = value

    @RedisCacheable(keyTemplate = cacheKeyTemplate)
    fun cacheMap(key: String, value: Map<String, Any?>?): Map<String, Any?>? = value

    @RedisCacheEvict(keyTemplate = cacheKeyTemplate)
    fun evictCache(key: String, value: String?) {
    }

    // 支持过期时间的缓存
    @RedisCacheable(keyTemplate = cacheKeyTemplate, expire = 1)
    fun cacheWithExpire(key: String, value: String?): String? = value

    // 支持复杂表达式（对象属性、嵌套、拼接等）
    data class User(val id: Long, val name: String)
    data class Order(val id: Long, val user: User, val items: List<String>)

    @RedisCacheable(keyTemplate = "cacheKeyPrefix:#{order.user.id}:#{order.items[0]}")
    fun cacheOrder(order: Order): String = "order:${order.id}:${order.user.id}:${order.items[0]}"

    // 可重复Evict，复杂表达式
    @RedisCacheEvict(keyTemplate = "cacheKeyPrefix:#{key}:#{value}")
    @RedisCacheEvict(keyTemplate = "cacheKeyPrefix:#{key}:#{value2}")
    fun evictMulti(key: String, value: Any?, value2: Any?) {
    }

    // ========== RedisCacheableMap 和 RedisCacheMapEvict 测试方法 ==========

    /**
     * 测试 RedisCacheableMap 注解 - 基础字符串类型
     *
     * @param key 缓存键
     * @param hashKey hash键
     * @param value 缓存值
     * @return 缓存的值
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheableMap(
        keyTemplate = "mapCache:#{key}",
        hashKeyTemplate = "hash:#{hashKey}"
    )
    fun cacheMapString(key: String, hashKey: String, value: String?): String? = value

    /**
     * 测试 RedisCacheableMap 注解 - 整数类型
     *
     * @param key 缓存键
     * @param hashKey hash键
     * @param value 缓存值
     * @return 缓存的值
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheableMap(
        keyTemplate = "mapCache:#{key}",
        hashKeyTemplate = "hash:#{hashKey}"
    )
    fun cacheMapInt(key: String, hashKey: String, value: Int?): Int? = value

    /**
     * 测试 RedisCacheableMap 注解 - 对象类型
     *
     * @param key 缓存键
     * @param hashKey hash键
     * @param value 缓存值
     * @return 缓存的值
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheableMap(
        keyTemplate = "mapCache:#{key}",
        hashKeyTemplate = "hash:#{hashKey}"
    )
    fun cacheMapObj(key: String, hashKey: String, value: SimpleObj?): SimpleObj? = value

    /**
     * 测试 RedisCacheableMap 注解 - 复杂表达式
     *
     * @param user 用户对象
     * @param order 订单对象
     * @return 缓存的值
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheableMap(
        keyTemplate = "userCache:#{user.id}",
        hashKeyTemplate = "order:#{order.id}:#{order.user.name}"
    )
    fun cacheMapComplex(user: User, order: Order): String = "user:${user.id}:order:${order.id}"

    /**
     * 测试 RedisCacheMapEvict 注解 - 基础删除
     *
     * @param key 缓存键
     * @param hashKey hash键
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheMapEvict(
        keyTemplate = "mapCache:#{key}",
        hashKeyTemplate = "hash:#{hashKey}"
    )
    fun evictMapCache(key: String, hashKey: String) {
    }

    /**
     * 测试 RedisCacheMapEvict 注解 - 复杂表达式删除
     *
     * @param user 用户对象
     * @param order 订单对象
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheMapEvict(
        keyTemplate = "userCache:#{user.id}",
        hashKeyTemplate = "order:#{order.id}:#{order.user.name}"
    )
    fun evictMapCacheComplex(user: User, order: Order) {
    }

    /**
     * 测试可重复 RedisCacheMapEvict 注解
     *
     * @param key1 第一个缓存键
     * @param hashKey1 第一个hash键
     * @param key2 第二个缓存键
     * @param hashKey2 第二个hash键
     * @author tangli
     * @date 2025/01/21 10:00
     */
    @RedisCacheMapEvict(
        keyTemplate = "mapCache:#{key1}",
        hashKeyTemplate = "hash:#{hashKey1}"
    )
    @RedisCacheMapEvict(
        keyTemplate = "mapCache:#{key2}",
        hashKeyTemplate = "hash:#{hashKey2}"
    )
    fun evictMultiMapCache(key1: String, hashKey1: String, key2: String, hashKey2: String) {
    }
}
